<!--
 * 页面根元素
 * 用来统一管理页面公共元素和逻辑等
 *
 * @author 济南晨霜信息技术有限公司
 * @mobile 18560000860 / 18754137913
 -->

<template>
    <view class="page-root" :class="_classes" :style="_styles">
        <!-- 页头 - 放置状态栏、导航栏 -->
        <view class="page-root__header" v-if="header">
            <view class="page-root__header__content">
                <hi-status-bar :autoBg="false"></hi-status-bar>
                <hi-navigation-bar :title="title" :align="align" v-bind="navOpts" :autoBg="false" @menuClick="onHeaderMenuClick"></hi-navigation-bar>
            </view>
        </view>

        <!-- 放置顶部全局通知等元素 -->
        <view class="page-root__topic">
            <hi-notice-bar
                class="global-notice-bar"
                :list="globalNoticeBarData"
                :show="globalNoticeBarShow"
                @close="globalNoticeBarShow = false"
                tint
                close
            ></hi-notice-bar>
        </view>

        <!-- 放置页面主内容 -->
        <view class="page-root__content">
            <slot></slot>
        </view>

        <!-- 页脚 - 放置 TabBar -->
        <view class="page-root__footer" v-if="footer"></view>

        <!-- 放置全局弹窗等元素 -->
        <view class="page-root__bottom">
            <!-- 一个全局弹窗示例 -->
            <hi-popup :show="globalPopupShow" title="将进酒·君不见" @close="globalPopupShow = false">
                <view style="padding: 0.5em 1.5em; text-align: justify; line-height: 1.8; font-size: 26rpx">
                    <view>君不见，黄河之水天上来，奔流到海不复回。</view>
                    <view>君不见，高堂明镜悲白发，朝如青丝暮成雪。</view>
                    <view>人生得意须尽欢，莫使金樽空对月。</view>
                    <view>天生我材必有用，千金散尽还复来。</view>
                    <view>烹羊宰牛且为乐，会须一饮三百杯。</view>
                    <view>岑夫子，丹丘生，将进酒，杯莫停。</view>
                    <view>与君歌一曲，请君为我倾耳听。</view>
                    <view>钟鼓馔玉不足贵，但愿长醉不愿醒。</view>
                    <view>古来圣贤皆寂寞，惟有饮者留其名。</view>
                    <view>陈王昔时宴平乐，斗酒十千恣欢谑。</view>
                    <view>主人何为言少钱，径须沽取对君酌。</view>
                    <view>五花马，千金裘，呼儿将出换美酒，与尔同销万古愁。</view>
                </view>
                <template #footer>
                    <view style="padding: 1em 2em; font-size: 0.85em; color: #999999; text-align: right; width: 100%">【作者】李白 【朝代】唐</view>
                </template>
            </hi-popup>
        </view>
    </view>
</template>

<!-- 由于 HbuilderX 不支持 defineOptions() 写法，故只能在此处进行配置 -->
<script>
    export default { options: uni?.$hi?.config?.componentsOptions || {} };
</script>

<script setup>
    import { ref, computed, onMounted, getCurrentInstance, nextTick, provide } from "vue";
    import { onPageScroll } from "@dcloudio/uni-app";
    import props from "./props.js";
    import { usePlatformStore } from "@/stores";
    import { sleep, uniGetNodeRectInfo, uniGetCurrentPageData } from "@/uni_modules/hi-ui/functions";
    import pagesJson from "@/pages.json";

    // vue 实例
    const currentInstance = getCurrentInstance();

    // stores
    const platformStore = usePlatformStore();

    // props
    const _props = defineProps(props);

    // emits
    const _emits = defineEmits([""]);

    // classes
    const _classes = computed(() => {
        const classes = [];

        // Header 模式
        const headerModes = _props.headerMode.split(" ");
        headerModes.forEach((mode) => classes.push(`page-root--header-mode--${mode}`));

        // Header 滚动后的模式
        const headerScrollModes = _props.headerScrollMode.split(" ");
        if (scrollTop.value) headerScrollModes.forEach((mode) => classes.push(`page-root--header-scroll-mode--${mode}`));

        return classes;
    });

    // styles
    const _styles = computed(() => {
        const styles = [];

        // 状态栏布局信息
        const _statusBarInfo = statusBarInfo.value;
        styles.push(`--page-status-bar-height: ${_statusBarInfo?.height || 0}px`);
        styles.push(`--page-status-bar-width: ${_statusBarInfo?.width || 0}px`);
        styles.push(`--page-status-bar-top: ${_statusBarInfo?.top || 0}px`);
        styles.push(`--page-status-bar-bottom: ${_statusBarInfo?.bottom || 0}px`);
        styles.push(`--page-status-bar-left: ${_statusBarInfo?.left || 0}px`);
        styles.push(`--page-status-bar-right: ${_statusBarInfo?.right || 0}px`);

        // 导航栏布局信息
        const _navigationBarInfo = navigationBarInfo.value;
        styles.push(`--page-navigation-bar-height: ${_navigationBarInfo?.height || 0}px`);
        styles.push(`--page-navigation-bar-width: ${_navigationBarInfo?.width || 0}px`);
        styles.push(`--page-navigation-bar-top: ${_navigationBarInfo?.top || 0}px`);
        styles.push(`--page-navigation-bar-bottom: ${_navigationBarInfo?.bottom || 0}px`);
        styles.push(`--page-navigation-bar-left: ${_navigationBarInfo?.left || 0}px`);
        styles.push(`--page-navigation-bar-right: ${_navigationBarInfo?.bottom || 0}px`);

        // header 布局信息
        const _headerInfo = headerInfo.value;
        styles.push(`--page-header-height: ${_headerInfo?.height || 0}px`);
        styles.push(`--page-header-width: ${_headerInfo?.width || 0}px`);
        styles.push(`--page-header-top: ${_headerInfo?.top || 0}px`);
        styles.push(`--page-header-bottom: ${_headerInfo?.bottom || 0}px`);
        styles.push(`--page-header-left: ${_headerInfo?.left || 0}px`);
        styles.push(`--page-header-right: ${_headerInfo?.bottom || 0}px`);

        // footer 布局信息
        const _footerInfo = footerInfo.value;
        styles.push(`--page-footer-height: ${_footerInfo?.height || 0}px`);
        styles.push(`--page-footer-width: ${_footerInfo?.width || 0}px`);
        styles.push(`--page-footer-top: ${_footerInfo?.top || 0}px`);
        styles.push(`--page-footer-bottom: ${_footerInfo?.bottom || 0}px`);
        styles.push(`--page-footer-left: ${_footerInfo?.left || 0}px`);
        styles.push(`--page-footer-right: ${_footerInfo?.bottom || 0}px`);

        // 页面滚动距离
        styles.push(`--page-scroll-top: ${scrollTop.value}px`);

        // 页面滚动距离与 Header 高度的比例
        if (_headerInfo?.height) styles.push(`--page-scroll-header-ratio: ${scrollTop.value / _headerInfo.height}`);
        else styles.push(`--page-scroll-header-ratio: 0`);

        // Header 的背景默认设置为 pages.json 中的配置值
        styles.push(
            `--page-header-background-default: ${
                currentPageData.value?.style?.navigationBarBackgroundColor || pagesJson?.globalStyle?.navigationBarBackgroundColor
            }`
        );

        // Header 的文字颜色默认设置为 pages.json 中的配置值
        styles.push(`--page-header-color-default: ${currentPageData.value?.style?.navigationBarTextStyle || pagesJson?.globalStyle?.navigationBarTextStyle}`);

        return styles;
    });

    // ----------------------------------------------------------------------------------------------------
    // - 元素布局信息
    // ----------------------------------------------------------------------------------------------------
    const statusBarInfo = ref(null); // 状态栏
    const navigationBarInfo = ref(null); // 导航栏
    const headerInfo = ref(null); // Header
    const footerInfo = ref(null); // Footer

    // 等组件渲染完成后再获取布局信息
    onMounted(async () => {
        // nextTick 一下
        await nextTick();

        // 再等待一下，确保能正确获取到数据
        await sleep(200);

        // 查询状态栏布局信息
        uniGetNodeRectInfo(".hi-status-bar", currentInstance).then((data) => (statusBarInfo.value = data));

        // 查询导航栏布局信息
        uniGetNodeRectInfo(".hi-navigation-bar", currentInstance).then((data) => (navigationBarInfo.value = data));

        // 查询 Header 布局信息
        uniGetNodeRectInfo(".page-root__header", currentInstance).then((data) => (headerInfo.value = data));

        // 查询 Footer 布局信息
        uniGetNodeRectInfo(".page-root__footer", currentInstance).then((data) => (footerInfo.value = data));
    });

    // ----------------------------------------------------------------------------------------------------
    // - 当前页面在 pages.json 中的配置信息
    // ----------------------------------------------------------------------------------------------------
    // 当前页面在 pages.json 中的配置信息
    const currentPageData = ref(null);

    // 组件渲染完成后获取当前页面在 pages.json 中的配置信息
    onMounted(() => (currentPageData.value = uniGetCurrentPageData()));

    // ----------------------------------------------------------------------------------------------------
    // - 全局通知
    // ----------------------------------------------------------------------------------------------------
    // 全局通知显示状态
    const globalNoticeBarShow = ref(false);

    // 全局通知数据
    const globalNoticeBarData = computed(() => platformStore?.notice || []);

    // 显示全局通知
    uni.$on("showGlobalNoticeBar", () => (globalNoticeBarShow.value = true));

    // ----------------------------------------------------------------------------------------------------
    // - 全局弹窗
    // ----------------------------------------------------------------------------------------------------
    // 全局弹窗显示状态
    const globalPopupShow = ref(false);

    // 显示全局弹窗
    uni.$on("showGlobalPopup", () => (globalPopupShow.value = true));

    // ----------------------------------------------------------------------------------------------------
    // - 页面滚动
    // ----------------------------------------------------------------------------------------------------
    // 页面滚动距离
    const scrollTop = ref(0);

    // 页面滚动事件
    onPageScroll((event) => (scrollTop.value = event.scrollTop));

    // 向下提供公共全局数据
    provide("scrollTop", scrollTop);

    function onHeaderMenuClick(menu, index, type) {
        console.log("点击了菜单", menu, index, type);
    }
</script>

<style lang="scss" scoped>
    .page-root {
        display: flex;
        flex-direction: column;
        position: relative;
        min-height: 100vh;
        // #ifdef H5
        min-height: calc(100vh - var(--window-top) - var(--window-bottom));
        // #endif

        &__header,
        &__footer {
            flex-shrink: 0;
        }

        &__header {
            position: sticky;
            top: 0px;
            z-index: var(--hi-index-upper);
            color: var(--page-header-color, var(--page-header-color-default));

            &__content {
                position: relative;
                z-index: 8;
            }

            &::after {
                content: "";
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                width: 100%;
                height: 100%;
                z-index: 0;
                background: var(--page-header-background, var(--page-header-background-default));
            }
        }

        &__footer {
            position: sticky;
            bottom: 0;
            z-index: var(--hi-index-upper);
        }

        &__content {
            flex: 1;
            display: flex;
            flex-direction: column;
        }

        &__topic {
            flex-shrink: 0;
            position: sticky;
            top: var(--app-header-height);
            z-index: var(--hi-index-default);
        }

        &__bottom {
            position: fixed;
            height: 0;
            bottom: 0;
            left: 0;
            z-index: var(--hi-index-upper);
        }

        // 滚动通知
        .hi-notice-bar {
            color: #f9ae3d;
            padding: 8px var(--g0);
            background: #fdf6ec;
        }

        // Header 模式
        &--header-mode {
            // 不显示 Header 模式
            &--none {
                .page-root__header {
                    display: none;
                }
            }

            // 隐藏标题模式
            &--hide-title {
                .page-root_header {
                    --hi-navigation-bar-center-display: none;
                }
            }

            // 透明背景模式
            &--bg-transparent {
                .page-root__header {
                    &::after {
                        background: var(--page-header-background, transparent);
                    }
                }
            }

            // 白色背景模式
            &--bg-white {
                .page-root__header {
                    &::after {
                        background: var(--page-header-background, white);
                    }
                }
            }

            // 黑色背景模式
            &--bg-black {
                .page-root__header {
                    &::after {
                        background: var(--page-header-background, black);
                    }
                }
            }

            // 白色文字模式
            &--color-white {
                .page-root__header {
                    color: var(--page-header-color, white);
                }
            }

            // 黑色文字模式
            &--color-black {
                .page-root__header {
                    color: var(--page-header-color, black);
                }
            }
        }

        // Header 滚动模式
        &--header-scroll-mode {
            // 整体动态透明度模式
            &--dynamic-opacity {
                .page-root__header {
                    opacity: var(--page-scroll-header-ratio);
                }
            }

            // 背景动态透明度模式
            &--bg-dynamic-opacity {
                .page-root__header {
                    &::after {
                        opacity: var(--page-scroll-header-ratio);
                    }
                }
            }
        }
    }
</style>
